/*
 * Copyright (c) 2017, 1DAOYUN and/or its affiliates. All rights reserved.
 * 1DAOYUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
 */
package com.iot.nev.gateway.collector.tcp;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.channel.AdaptiveRecvByteBufAllocator;
import io.netty.channel.ChannelInitializer;
import io.netty.channel.ChannelOption;
import io.netty.channel.ChannelPipeline;
import io.netty.channel.EventLoopGroup;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.SocketChannel;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.handler.codec.string.StringDecoder;
import io.netty.handler.codec.string.StringEncoder;
import io.netty.util.CharsetUtil;

import java.util.Properties;

import org.apache.log4j.Logger;

import com.iot.nev.gateway.collector.Collector;
import com.iot.nev.gateway.router.Router;
import com.iot.nev.gateway.utils.UtilTools;

/**
 * 使用Netty构建TCPServer，进行数据的接收。接收后，进行转码。转码后直接派发到
 * 
 * @author WangHuanHuan
 * @since v1.0 (2017.10)
 * @version v1.0
 */
public class NettyTCPServer implements Collector {
	// logger
	private Logger logger = Logger.getLogger(NettyTCPServer.class);
	// config
	private Properties config = UtilTools.getConfig(System.getProperty("user.dir") + "/configuration/config.properties");

	// parent thread
	private EventLoopGroup parentGroup;
	// child thread
	private EventLoopGroup childGroup;
	//server bootstrap
	private ServerBootstrap sb;
	
	int num=1;
	long s = System.currentTimeMillis();
	
	/**
	 * 创建NettyTCPServer。
	 */
	
	/**
	 * 启动网关服务。
	 */
	public void init() {
		try {
			// ip address(this host)
			// port
			String serverPort = config.getProperty("collector_tcp_server_port");
			// parent thread count
			String parentThread = config.getProperty("collector_tcp_server_netty_parent_thread");
			// child thread count
			String childThread = config.getProperty("collector_tcp_server_netty_child_thread");

			parentGroup = new NioEventLoopGroup(Integer.valueOf(parentThread));
			childGroup = new NioEventLoopGroup(Integer.valueOf(childThread));

			// create server bootstrap
			sb = new ServerBootstrap();
			// set group
			sb.group(parentGroup, childGroup);
			// set channel
			sb.channel(NioServerSocketChannel.class);
			// no delay
			sb.option(ChannelOption.TCP_NODELAY, true);
			// buffer allocator
			sb.option(ChannelOption.RCVBUF_ALLOCATOR, AdaptiveRecvByteBufAllocator.DEFAULT);
			//create a initializer
			sb.childHandler(new ChannelInitializer<SocketChannel>() {
				@Override
				public void initChannel(SocketChannel ch) throws Exception {
					long e = System.currentTimeMillis();
					if(e-s >= 60000){
						System.out.println(num + "---" + (e-s));
						System.exit(0);
					}
					num++;
					ChannelPipeline pipeline = ch.pipeline();
					pipeline.addLast("decoder", new StringDecoder(CharsetUtil.UTF_8));
					pipeline.addLast("encoder", new StringEncoder(CharsetUtil.UTF_8));
					pipeline.addLast(new NettyTCPServerHandler());
				}
			});
			sb.bind(Integer.valueOf(serverPort)).sync();
		} catch (InterruptedException exception) {
			logger.error("## Start Error:" + exception.toString());
		}
		logger.info("## Netty TCPServer finished to start");
	}

	/**
	 * 启动网关服务。
	 */
	
	public void start() {
		logger.info("## Netty TCPServer begins to start");
		init();
	}

	/**
	 * 停止网关服务。
	 */
	
	public void stop() {
		parentGroup.shutdownGracefully();
		childGroup.shutdownGracefully();
	}

	/**
	 * 重启网关服务。
	 */
	
	public void restart() {
		this.stop();
		this.start();
	}

	public boolean isActive() {
		return false;
	}
	
	public int getConnectedCount() {
		return 0;
	}
	
	public float getServiceLevel() {
		return 0;
	}

	public Router getRouter() {
		return null;
	}

	public Collector getCollector() {
		return this;
	}

}